#include <iostream>
#include <memory>
#include <functional>

struct T{
    void foo(){ std::cout << __FUNCTION__ << std::endl; }
    int a = 5;
};

struct MyDeleter
{
    void operator()(int *p)
    {
        std::cout << "delete" << std::endl;
        delete p;
    }
};

int main(void)
{
    //unique_ptr 不允许复制
    {
        std::unique_ptr<T> myPtr(new T);
        //std::unique_ptr<T> myOtherPtr = myPtr; // error
        std::unique_ptr<T> ptr = std::move(myPtr); //但是可以移动
    }


    //unique_ptr 除了独占属性外，还可以指向一个数组
    {
        std::unique_ptr<int[]> ptr(new int [10]);
        ptr[9] = 9; //通过智能指针访问 数组元素

        {
            //而shared_ptr 则不能指向一个数组
            //st::shared_ptr<int[]> ptr(new int[10]);
        }
    }

    {
        //std::unique_ptr 指定删除函数时，需要确定删除函数的类型
        std::unique_ptr<int, void(*)(int*)> ptr(new int(1), [](int *p){ delete p; });
        //如果 lambda 需要捕获变量时，则需要这么写 
        std::unique_ptr<int, std::function<void(int*)>> ptr_p(new int(1), [&](int *p){ delete p; });
        //int a = [](int* p){}; //<lambda(int*)>::operator void (*)(int*)()
        //int a = [&](int * p){}; //<lambda(int*)>
        //在 lambda 在没有捕获变量的情况下时可以直接转换为函数指针的，一旦捕获了就无法转换了。
        

        //自定义 unique_ptr 的删除器
        std::unique_ptr<int, MyDeleter> p(new int(1));
    }

    return 0;
}
//关于shared_ptr 和 unique_ptr 的使用场景：如果只有一个智能指针管理资源或者管理数组就用 unique_ptr。
//如果希望多个智能指针管理同一个资源就用 shared_ptr
